package com.egao.common.module.world.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.egao.common.core.exception.BusinessException;
import com.egao.common.core.utils.CoreUtil;
import com.egao.common.core.web.JsonResult;
import com.egao.common.core.web.PageParam;
import com.egao.common.module.cooperative.constants.CooperativeProjectConstants;
import com.egao.common.module.student.entity.Student;
import com.egao.common.module.student.service.StudentService;
import com.egao.common.module.system.constants.UserConstants;
import com.egao.common.module.system.entity.User;
import com.egao.common.module.world.WorldGameConstants;
import com.egao.common.module.world.entity.WorldGame;
import com.egao.common.module.world.entity.WorldGameStudent;
import com.egao.common.module.world.mapper.WorldGameStudentMapper;
import com.egao.common.module.world.service.WorldGameService;
import com.egao.common.module.world.service.WorldGameStudentService;
import com.egao.common.module.world.vo.WorldGameStudentBtn;
import com.egao.common.module.world.vo.WorldGameStudentVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * WorldGameStudent Service Impl
 *
 * @author root
 */
@Service
public class WorldGameStudentServiceImpl extends ServiceImpl<WorldGameStudentMapper, WorldGameStudent> implements WorldGameStudentService {

    @Autowired
    private StudentService studentService;
    @Autowired
    private WorldGameService worldGameService;

    @Override
    public List<WorldGameStudent> listPage(PageParam<WorldGameStudent> page) {
        return baseMapper.listPage(page);
    }

    @Override
    public JsonResult updatePrize(WorldGameStudent worldGameStudent) {
        if (null == worldGameStudent) {
            throw new BusinessException("参数异常");
        }

        if (null == worldGameStudent.getId()) {
            throw new BusinessException("主键异常");
        }
        //根据获奖级别设置分数
        switch (worldGameStudent.getPrizeLevel()) {
            case WorldGameConstants.PRIZE_LEVEL_1:
                worldGameStudent.setScore(7);
                break;
            case WorldGameConstants.PRIZE_LEVEL_2:
                worldGameStudent.setScore(6);
                break;
            case WorldGameConstants.PRIZE_LEVEL_3:
                worldGameStudent.setScore(5);
                break;
            case WorldGameConstants.PRIZE_LEVEL_4:
                worldGameStudent.setScore(4);
                break;
        }

        worldGameStudent.setPrizeTime(new Date());
        if (updateById(worldGameStudent)) {
            return JsonResult.ok("修改成功");
        }
        return JsonResult.error("修改失败");
    }

    @Override
    public JsonResult updateGameState(WorldGameStudent worldGameStudent) {
        if (null == worldGameStudent) {
            throw new BusinessException("参数异常");
        }

        if (null == worldGameStudent.getId()) {
            throw new BusinessException("主键异常");
        }

        // 根据比赛状态设置分数
        switch (worldGameStudent.getGameState()) {
            case WorldGameConstants.GAME_STATE_APPLY:
             worldGameStudent.setScore(1);
                break;
            case WorldGameConstants.GAME_STATE_REMATCH:
                worldGameStudent.setScore(2);
                break;
            case WorldGameConstants.GAME_STATE_FINAL:
                worldGameStudent.setScore(3);
                break;
        }

        // 当获奖等级存在时，不能通过比赛状态修改分数
        WorldGameStudent old = baseMapper.selectById(worldGameStudent.getId());
        if(!StrUtil.isBlank(old.getPrizeLevel())) {
            worldGameStudent.setScore(null);
        }

        if (updateById(worldGameStudent)) {
            return JsonResult.ok("修改成功");
        }
        return JsonResult.error("修改失败");
    }

    @Override
    public WorldGameStudentBtn initBtn(Integer worldGameId, User user) {
        if (user == null) {
            return new WorldGameStudentBtn("请先登录");
        }

        if (!UserConstants.USER_TYPE_STUDENT.equals(user.getUserType())) {
            return new WorldGameStudentBtn("仅限学生报名");
        }

        Student student = studentService.getByUserId(user.getUserId());
        if (student == null) {
            return new WorldGameStudentBtn("账号信息异常请联系就业中心");
        }

        WorldGame worldGame = worldGameService.getById(worldGameId);

        WorldGameStudent worldGameStudent = baseMapper.selectOne(new QueryWrapper<WorldGameStudent>().lambda()
                .eq(WorldGameStudent::getWorldGameId, worldGameId)
                .eq(WorldGameStudent::getStudentId, student.getId())
                .last("limit 1")
        );


        if (worldGameStudent != null) {
            switch (worldGameStudent.getState()) {
                case WorldGameConstants.STATE_SUCCESS:
                    if (System.currentTimeMillis() > worldGame.getCloseTime().getTime()) {
                        return new WorldGameStudentBtn("已报名");
                    } else {
                        return new WorldGameStudentBtn("取消报名", false, worldGameStudent.getId());
                    }
                case CooperativeProjectConstants.CPAS_STATE_CANCEL:
                    return new WorldGameStudentBtn("已取消报名");
                case WorldGameConstants.STATE_FAIL:
                    return new WorldGameStudentBtn("报名审核不通过", false, worldGameStudent.getId());
                case WorldGameConstants.STATE_WAIT:
                    return new WorldGameStudentBtn("报名审核中 - 取消报名", false, worldGameStudent.getId());
                default:
            }
        }

        if (System.currentTimeMillis() > worldGame.getCloseTime().getTime()) {
            return new WorldGameStudentBtn("报名已截止");
        }

        Integer countApply = baseMapper.selectCount(new QueryWrapper<WorldGameStudent>().lambda()
                .eq(WorldGameStudent::getWorldGameId, worldGameId)
                .eq(WorldGameStudent::getState, WorldGameConstants.STATE_SUCCESS)
        );
        if (countApply >= worldGame.getNumber()) {
            return new WorldGameStudentBtn("报名名额已满");
        }

        return new WorldGameStudentBtn("报名", false);
    }

    @Override
    public JsonResult apply(WorldGameStudent worldGameStudent, User user) {
        if (null == worldGameStudent) {
            throw new BusinessException("参数异常");
        }

        if (null == worldGameStudent.getWorldGameId()) {
            throw new BusinessException("济世杯参数异常");
        }

        WorldGameStudentBtn btn = initBtn(worldGameStudent.getWorldGameId(), user);
        if ("报名".equals(btn.getTitle()) && !btn.isDisabled()) {
            WorldGame worldGame = worldGameService.getById(worldGameStudent.getWorldGameId());
            if (worldGame == null) {
                return JsonResult.error("没有找到济世杯信息");
            }

            if (WorldGameConstants.CHECK_STATE_YES.equals(worldGame.getCheckState())) {
                worldGameStudent.setState(WorldGameConstants.STATE_WAIT);
            } else {
                worldGameStudent.setState(WorldGameConstants.STATE_SUCCESS);
                worldGameStudent.setGameState(WorldGameConstants.GAME_STATE_APPLY);
                worldGameStudent.setScore(1);
            }

            Student student = studentService.getByUserId(user.getUserId());
            worldGameStudent.setStudentId(student.getId());
            if (save(worldGameStudent)) {
                return JsonResult.ok("报名成功");
            }
            return JsonResult.error("报名失败");
        }

        return JsonResult.error(btn.getTitle());
    }

    @Override
    public JsonResult cancel(WorldGameStudent worldGameStudent) {
        worldGameStudent.setState(WorldGameConstants.STATE_CANCEL);
        worldGameStudent.setCancelTime(new Date());
        if (updateById(worldGameStudent)) {
            return JsonResult.ok("取消成功");
        }
        return JsonResult.error("取消失败");
    }

    @Override
    public JsonResult importStudentGameState(MultipartFile file, Integer worldGameId) {
        if (null == worldGameId) {
            throw new BusinessException("参数异常");
        }

        StringBuilder sb = new StringBuilder();
        try {
            // 读取Excel
            int startRow = 1;
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream(), 0);
            List<List<Object>> list = reader.read(startRow);

            // 进行非空和重复检查
            sb.append(CoreUtil.excelCheckBlank(list, startRow, 0));
            sb.append(CoreUtil.excelCheckRepeat(list, startRow, 0));
            if (!sb.toString().isEmpty()) {
                return JsonResult.error(sb.toString());
            }

            if (list.size() == 0) {
                return JsonResult.error("导入模板无数据");
            }

            List<WorldGameStudent> updateList = new ArrayList<>();
            for (List<Object> objects : list) {
                String xh = String.valueOf(objects.get(0));
                String stateName = String.valueOf(objects.get(1));

                WorldGameStudent worldGameStudent = new WorldGameStudent();
                worldGameStudent.setXh(xh);

                if ("报名".equals(stateName)) {
                    worldGameStudent.setGameState(WorldGameConstants.GAME_STATE_APPLY);
                    worldGameStudent.setScore(1);
                }
                if ("复赛".equals(stateName)) {
                    worldGameStudent.setGameState(WorldGameConstants.GAME_STATE_REMATCH);
                    worldGameStudent.setScore(2);
                }
                if ("决赛".equals(stateName)) {
                    worldGameStudent.setGameState(WorldGameConstants.GAME_STATE_FINAL);
                    worldGameStudent.setScore(3);
                }
                if (StrUtil.isBlank(worldGameStudent.getGameState())) {
                    return JsonResult.error("学号" + xh + "的报名状态不符");
                }

                updateList.add(worldGameStudent);
            }

            // 学生
            List<String> xhList = updateList.stream().map(WorldGameStudent::getXh).collect(Collectors.toList());
            List<Student> studentList = studentService.list(new LambdaQueryWrapper<Student>()
                            .select(Student::getId, Student::getXh)
                            .in(Student::getXh, xhList)
            );

            // 当前济世杯所有报名记录
            List<WorldGameStudent> worldGameStudentList =
                    baseMapper.selectList(new LambdaQueryWrapper<WorldGameStudent>().eq(WorldGameStudent::getWorldGameId, worldGameId));

            for (WorldGameStudent item : updateList) {
                String xh = item.getXh();
                Integer studentId = studentList.stream().filter(d -> d.getXh().equals(xh)).map(Student::getId).findFirst().orElse(null);
                if (studentId == null) {
                    return JsonResult.error("学号" + xh + "没有找到学生信息");
                }
                item.setStudentId(studentId);

                WorldGameStudent worldGameStudent = worldGameStudentList.stream().filter(d -> studentId.equals(d.getStudentId())).findFirst().orElse(null);
                if (worldGameStudent == null) {
                    return JsonResult.error("学号" + xh + "没有报名本次济世杯");
                }
                if (WorldGameConstants.STATE_CANCEL.equals(worldGameStudent.getState())) {
                    return JsonResult.error("学号" + xh + "已取消本次济世杯报名");
                }
                // 有获奖状态 不更新比赛状态得分
                if (!StrUtil.isBlank(worldGameStudent.getPrizeLevel())) {
                    item.setScore(null);
                }
                item.setId(worldGameStudent.getId());
            }

            if (updateBatchById(updateList)) {
                return JsonResult.ok("导入完成");
            }

            return JsonResult.error("导入更新失败");
        } catch (IOException e) {
            e.printStackTrace();
        }

        return JsonResult.error("导入失败");
    }

    @Override
    public JsonResult importStudentPrizeLevel(MultipartFile file, Integer worldGameId, Integer loginUserId) {
        if (null == worldGameId) {
            throw new BusinessException("参数异常");
        }

        StringBuilder sb = new StringBuilder();
        try {
            // 读取Excel
            int startRow = 1;
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream(), 0);
            List<List<Object>> list = reader.read(startRow);

            // 进行非空和重复检查
            sb.append(CoreUtil.excelCheckBlank(list, startRow, 0));
            sb.append(CoreUtil.excelCheckRepeat(list, startRow, 0));
            if (!sb.toString().isEmpty()) {
                return JsonResult.error(sb.toString());
            }

            if (list.size() == 0) {
                return JsonResult.error("导入模板无数据");
            }

            List<WorldGameStudent> updateList = new ArrayList<>();
            for (List<Object> objects : list) {
                String xh = String.valueOf(objects.get(0));
                String stateName = String.valueOf(objects.get(1));

                WorldGameStudent worldGameStudent = new WorldGameStudent();
                worldGameStudent.setXh(xh);

                if ("一等奖".equals(stateName)) {
                    worldGameStudent.setPrizeLevel(WorldGameConstants.PRIZE_LEVEL_1);
                    worldGameStudent.setScore(7);
                }
                if ("二等奖".equals(stateName)) {
                    worldGameStudent.setPrizeLevel(WorldGameConstants.PRIZE_LEVEL_2);
                    worldGameStudent.setScore(6);
                }
                if ("三等奖".equals(stateName)) {
                    worldGameStudent.setPrizeLevel(WorldGameConstants.PRIZE_LEVEL_3);
                    worldGameStudent.setScore(5);
                }
                if ("优秀奖".equals(stateName)) {
                    worldGameStudent.setPrizeLevel(WorldGameConstants.PRIZE_LEVEL_4);
                    worldGameStudent.setScore(4);
                }
                if (StrUtil.isBlank(worldGameStudent.getPrizeLevel())) {
                    return JsonResult.error("学号" + xh + "的获奖状态不符");
                }

                updateList.add(worldGameStudent);
            }

            // 学生
            List<String> xhList = updateList.stream().map(WorldGameStudent::getXh).collect(Collectors.toList());
            List<Student> studentList = studentService.list(new LambdaQueryWrapper<Student>()
                    .select(Student::getId, Student::getXh)
                    .in(Student::getXh, xhList)
            );

            // 当前济世杯所有报名记录
            List<WorldGameStudent> worldGameStudentList =
                    baseMapper.selectList(new LambdaQueryWrapper<WorldGameStudent>().eq(WorldGameStudent::getWorldGameId, worldGameId));

            for (WorldGameStudent item : updateList) {
                String xh = item.getXh();
                Integer studentId = studentList.stream().filter(d -> d.getXh().equals(xh)).map(Student::getId).findFirst().orElse(null);
                if (studentId == null) {
                    return JsonResult.error("学号" + xh + "没有找到学生信息");
                }
                item.setStudentId(studentId);

                WorldGameStudent worldGameStudent = worldGameStudentList.stream().filter(d -> studentId.equals(d.getStudentId())).findFirst().orElse(null);
                if (worldGameStudent == null) {
                    return JsonResult.error("学号" + xh + "没有报名本次济世杯");
                }
                if (WorldGameConstants.STATE_CANCEL.equals(worldGameStudent.getState())) {
                    return JsonResult.error("学号" + xh + "已取消本次济世杯报名");
                }
                item.setId(worldGameStudent.getId());
                item.setPrizeBy(loginUserId);
                item.setPrizeTime(new Date());
            }

            if (updateBatchById(updateList)) {
                return JsonResult.ok("导入完成");
            }

            return JsonResult.error("导入更新失败");
        } catch (IOException e) {
            e.printStackTrace();
        }

        return JsonResult.error("导入失败");
    }
}
